
/**
 * AppleIIGo
 * SDL I/O class
 * (C) 2007-2008 by Marc S. Ressl (mressl@umich.edu)
 * Released under the GPL
 */

#ifndef SDLIO_H
#define SDLIO_H

#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#include "Motherboard.h"

#define SDLIO_VIDEO_X			FRAMEBUFFER_X
#define SDLIO_VIDEO_Y			FRAMEBUFFER_Y

#define SDLIO_AUDIO_SAMPLENUM			8192
#define SDLIO_AUDIO_SAMPLERATE			48000
#define SDLIO_AUDIO_VOLUMEFILTERFACTOR	(400.0 / SDLIO_AUDIO_SAMPLERATE)

#define saturateAudio(value) (((value) > 32767) ? 32767 : ((value) < -32768) \
	? 32768 : (value))

int sdlThread(void * userdata);
void sdlCallback(void * userdata, Uint8 * stream, int len);

class SDLIO {
public:
	SDLIO();
	~SDLIO();
	
	bool open(class Motherboard * motherboard, char * caption);
	bool reopen();
	void close();
	
	void lock();
	void unlock();
	void setThreadPaused(bool value);
	bool isThreadPaused();
	void runThread();
	
	void setAudioVolume(float value);
	void callbackAudio(SINT16 * sampleData, UINT32 sampleNum);
	
	void setVideoFullscreen(bool value);
	void toggleVideoFullscreen();
	bool isVideoFullscreen();
	
	void eventLoop();
	bool quit();
	
private:
	class Motherboard * motherboard;
	
	SDL_mutex * mutex;
	SDL_cond * cond;
	SDL_Thread * thread;
	bool isThreadPausedValue;
	bool isKillThreadSignal;
	
	bool isPalTiming;
	SINT32 * audioInputBuffer;
	SINT32 * audioOutputBuffer;
	UINT32 audioBufferSampleNum;
	UINT32 audioFrameSampleNum;
	float audioVolume;
	float currentAudioVolume;
	
	bool isFullscreenValue;
	SDL_Surface * videoSurface;
	char * videoCaption;
	
	class KeyDownList * keyDownList;
	UINT32 resetCount;
	
	bool isMouseCapturedValue;
	bool isFirstMouseMovementSkipped;
	bool isMouseButtonDown[MOUSEBUTTON_NUM];
	
	SDL_Joystick * joystick;
	
	void initThread();
	bool openThread();
	void closeThread();
	
	void initAudio();
	bool openAudio();
	void closeAudio();
	
	void initVideo();
	bool openVideo(char * caption);
	void closeVideo();
	
	void initKeyboard();
	void openKeyboard();
	void closeKeyboard();
	void pushKeyboardKey(UINT32 sym, UINT32 mod, UINT32 unicode);
	void pullKeyboardKey(UINT32 sym, UINT32 mod, UINT32 unicode);
	UINT32 getKeyboardModifierIndex(UINT32 sym);
	
	void initMouse();
	void openMouse();
	void closeMouse();
	void moveMouse(SINT32 xRel, SINT32 yRel);
	void pushMouseButton(UINT32 button);
	void pullMouseButton(UINT32 button);
	void clearMouseButtons();
	void captureMouse();
	void releaseMouse();
	bool isMouseCaptured();
	UINT32 getMouseButtonIndex(UINT32 button);
	
	void initJoystick();
	void openJoystick();
	void closeJoystick();
	void setJoystickPosition(UINT32 axis, UINT32 value);
	void pushJoystickButton(UINT32 button);
	void pullJoystickButton(UINT32 button);
};

#endif
